﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;

namespace Xceed.Silverlight.Utils
{
  internal sealed class DeferableObservableCollection<T> : ObservableCollection<T>
  {
    public IDisposable DeferPropertyAndCollectionChanged()
    {
      return new DeferPropertyAndCollectionChangedDisposable( this );
    }

    protected override void OnCollectionChanged( System.Collections.Specialized.NotifyCollectionChangedEventArgs e )
    {
      if( m_deferCount > 0 )
        return;

      base.OnCollectionChanged( e );
    }

    protected override void OnPropertyChanged( System.ComponentModel.PropertyChangedEventArgs e )
    {
      if( m_deferCount > 0 )
        return;

      base.OnPropertyChanged( e );
    }

    private class DeferPropertyAndCollectionChangedDisposable : IDisposable
    {
      public DeferPropertyAndCollectionChangedDisposable( DeferableObservableCollection<T> deferable )
      {
        if( deferable == null )
          throw new ArgumentNullException( "deferable" );

        m_deferable = deferable;
        m_deferable.m_deferCount++;
      }

      public void Dispose()
      {
        if( m_deferable == null )
          return;

        m_deferable.m_deferCount--;

        if( m_deferable.m_deferCount == 0 )
        {
          m_deferable.OnPropertyChanged( new PropertyChangedEventArgs( "Count" ) );
          m_deferable.OnPropertyChanged( new PropertyChangedEventArgs( "Item[]" ) );
          m_deferable.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) );
        }

        m_deferable = null;
      }

      private DeferableObservableCollection<T> m_deferable;
    }

    private int m_deferCount; // = 0;
  }
}
